/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package genomemap.nb.jobs.properties;

import com.google.common.collect.ImmutableMap;
import commons.nb.jobs.properties.*;
import commons.nb.jobs.properties.editors.ValidatingInplaceEditor;
import commons.nb.jobs.properties.editors.ValidatingStringInplaceEditor;
import commons.util.TwoWayConverterS;
import commons.util.base.TwoWayConverter;
import genomemap.nb.jobs.properties.editors.LinkageGroupsPropertyEditor;
import genomemap.nb.jobs.properties.editors.PropertyEditors_Gen;
import org.netbeans.validation.api.Validator;

import java.io.File;
import java.util.List;

import static commons.nb.jobs.properties.SelectionProperty.Selection;

/**
 * @author Susanta Tewari
 * @version 1.0.0
 * @history Created on Dec 20, 2011
 * @since 1.0.0
 */
public class Propertys_Gen {

    /**
     * Private constructor to prevent instantiation.
     */
    private Propertys_Gen() {}

    /**
     * @return a new instance of the  property
     */
    public static Property<String> LINKAGE_GROUPS() {

        final Property<String> propimpl = Propertys.ofString();

        propimpl.setName("linkage-groups");
        propimpl.setDisplayName("Linkage Groups");
        propimpl.setShortDescription("Linkage Groups");
        propimpl.setPropertySet(PropertySets.DATA);


        // validator & inplace editor
        final Validator<String> validator = CommonsValidators.COMMA_DELIM_VALIDATOR;

        propimpl.setValidator(validator);
        propimpl.setPropEditorClass(LinkageGroupsPropertyEditor.class);


        // inplace editor
        final ValidatingInplaceEditor editor = new ValidatingStringInplaceEditor();

        editor.addValidator(validator);
        propimpl.getCustomParamValues().put("inplaceEditor", editor);


        // default value
        propimpl.setKey("genomemap.builder.OrganismData.linkage-groups");
        propimpl.setValue("1,2");

        return propimpl;
    }

    /**
     * @return a new instance of the property
     */
    public static Property<File> URL_DATA_Organism() {

        return Propertys.ofFile(
            "organism-data", "Whole organism data",
            "A directory containing the whole organism data", PropertySets.DATA,
            "genomemap.builder.OrganismData.url", "organismdata:files//",
            new File("C:/wspaces/genomemap/genomemap_data/organism_data_impl1"));
    }

    /**
     * Supplies the following property: <ul> <li>{@code genomemap.builder.TAB08Data.url =
     * tab08data:xml//URL }<a href="genomemap/cef/pui/pob/doc-files/tab08-data.xml.txt">file
     * format</a>, must accompany the <a href="genomemap/cef/pui/pob/doc-files/TAB08Data.xsd.txt">schema</a></li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<File> URL_DATA_TAB08() {

        return Propertys.ofFile(
            "tab08data", "TAB08 Model Data", "TAB08 Model Data in XML format",
            PropertySets.DATA, "genomemap.builder.TAB08Data.url", "tab08data:xml//",
            new File("C:/wspaces/genomemap/genomemap_data/files/tab08_data.xml"));
    }

    /**
     * Supplies the following property: <ul> <li>{@code genomemap.builder.KSA00Data.url =
     * ksa00data:xml//URL }<a href="genomemap/cef/pui/pob/doc-files/ksa00-data.xml.txt">file
     * format</a>, must accompany the <a href="genomemap/cef/pui/pob/doc-files/KSA00Data.xsd.txt">schema</a></li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<File> URL_DATA_KSA00() {

        return Propertys.ofFile(
            "ksa00data", "KSA00 Model Data", "KSA00 Model Data in XML format",
            PropertySets.DATA, "genomemap.builder.KSA00Data.url", "ksa00data:xml//",
            new File("C:/wspaces/genomemap/genomemap_data/files/ksa00_data.xml"));
    }

    /**
     * Supplies the following property: <ul> <li>{@code commons.builder.StringList.url =
     * stringlist:line-delimited//URL }</li> </ul>
     *
     * @return a new instance of the property
     */
    public static Property<File> URL_INPUT_GENES() {

        return Propertys.ofFile(
            "genes-data", "Genes collection file", "Contains genes (no spaces), one per line",
            PropertySets.DATA, "commons.builder.StringList.url",
            "stringlist:line-delimited//",
            new File("C:/wspaces/genomemap/genomemap_data/data/broad_all_gene_names.txt"));
    }

    /**
     * Supplies the following property: <ul> <li>{@code genomemap.builder.AssignmentData.url =
     * assignmentdata:csv//URL }</li> </ul>
     *
     * @return a new instance of the property
     */
    public static Property<File> URL_DATA_ASSIGNMENT() {

        return Propertys.ofFile(
            "complementation-data", "Gene-Clone complementation file",
            "Contains gene-clone complementation data, separated by ','."
            + " The first one is gene, followed by clones per line.", PropertySets.DATA,
                "genomemap.builder.AssignmentData.url", "assignmentdata:csv//",
                new File("C:/wspaces/genomemap/genomemap_data/data/arnold_compl_data.txt"));
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.TAB08DataSimulator.implCode = tab08data:1}</li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> SIMULATORS_DATA_TAB08() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("tab08-data-simulators");
        propimpl.setDisplayName("TAB08 Data Simulators");
        propimpl.setShortDescription("Simulates TAB08 Data");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Simulator_Data_TAB08Data.class);


        // key & value
        propimpl.setKey("genomemap.builder.TAB08DataSimulator.implCode");
        propimpl.setValue("tab08data:1");

        return propimpl;
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.KSA00DataSimulator.implCode = ksa00data:1}</li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> SIMULATORS_DATA_KSA00() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("ksa00-data-simulators");
        propimpl.setDisplayName("KSA00 Data Simulators");
        propimpl.setShortDescription("Simulates KSA00 Data");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Simulator_Data_KSA00Data.class);


        // key & value
        propimpl.setKey("genomemap.builder.KSA00DataSimulator.implCode");
        propimpl.setValue("ksa00data:1");

        return propimpl;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static BuilderProperty BUILDER_DATA_AssignmentData() {

        final BuilderProperty propImpl = Propertys.ofBuilder();

        propImpl.setName("assignment-data-builders");
        propImpl.setDisplayName("Assignment Data Sets");
        propImpl.setShortDescription("Assignment Data Sets");
        propImpl.setPropertySet(PropertySets.DATA);


        // property editor
        propImpl.setPropEditorClass(
            PropertyEditors_Gen.Builder_Data_AssignmentData_ExPE_IFactory.class);

        return propImpl;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static BuilderProperty BUILDER_DATA_KSA00Data() {

        final BuilderProperty propImpl = Propertys.ofBuilder();

        propImpl.setName("KSA00Data-builders");
        propImpl.setDisplayName("KSA00 Data Sets");
        propImpl.setShortDescription("KSA00 Data Sets");
        propImpl.setPropertySet(PropertySets.DATA);


        // property editor
        propImpl.setPropEditorClass(PropertyEditors_Gen.Builder_Data_KSA00Data_ExPE_IFactory.class);

        return propImpl;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static BuilderProperty BUILDER_DATA_TAB08Data() {

        final BuilderProperty propImpl = Propertys.ofBuilder();

        propImpl.setName("TAB08Data-builders");
        propImpl.setDisplayName("TAB08 Data Sets");
        propImpl.setShortDescription("TAB08 Data Sets");
        propImpl.setPropertySet(PropertySets.DATA);


        // property editor
        propImpl.setPropEditorClass(PropertyEditors_Gen.Builder_Data_TAB08Data_ExPE_IFactory.class);

        return propImpl;
    }

    /**
     * Method description
     *
     *
     * @return
     */
    public static BuilderProperty BUILDER_DATA_OrganismData() {

        final BuilderProperty propImpl = Propertys.ofBuilder();

        propImpl.setName("OrganismData-builders");
        propImpl.setDisplayName("Organism Data Sets");
        propImpl.setShortDescription("Organism Data Sets");
        propImpl.setPropertySet(PropertySets.DATA);


        // property editor
        propImpl.setPropEditorClass(
            PropertyEditors_Gen.Builder_Data_OrganismData_ExPE_IFactory.class);

        return propImpl;
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.TAB08Lhood.implCode = tab08:rla | tab08:sfa)</li>
     * </ul>
     * @return a new instance of the property
     */
    public static Property<String> ALGO_LHOOD_TAB08() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("tab08-lhood-algorithm");
        propimpl.setDisplayName("TAB08 LHood Algorithms");
        propimpl.setShortDescription("Likelihood algorithms for model TAB08");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Algo_LHood_TAB08.class);


        // key & value
        propimpl.setKey("genomemap.builder.TAB08Lhood.implCode");
        propimpl.setValue("tab08:rla");

        return propimpl;
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.KSA00Lhood.implCode = ksa00:1)</li>
     * </ul>
     * @return a new instance of the property
     */
    public static Property<String> ALGO_LHOOD_KSA00() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("ksa00-lhood-algorithm");
        propimpl.setDisplayName("KSA00 LHood Algorithms");
        propimpl.setShortDescription("Likelihood algorithms for model KSA00");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Algo_LHood_KSA00.class);


        // key & value
        propimpl.setKey("genomemap.builder.KSA00Lhood.implCode");
        propimpl.setValue("ksa00:1");

        return propimpl;
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.GeneticMapFunctions.implCode = haldane,kosambi)</li>
     * </ul>
     * @return a new instance of the property
     */
    public static Property<Selection[]> MAPPING_FUNCTIONS() {

        final ImmutableMap<String, String> map = ImmutableMap.of("haldane",
                                                     "Haldane Mapping Function", "kosambi",
                                                     "Kosambi Mapping Function");

        return Propertys.ofSelectionArray("mapping-fn", "Mapping Functions",
                                          "Genetic Mapping Functions",
                                          PropertySets.ALGORITHMS,
                                          "genomemap.builder.GeneticMapFunctions.implCode", map);
    }

    /**
     * Supplies the following property: <ul> <li>{@code genomemap.builder.TAB08Estimator.implCode =
     * tab08:interval-mle}</li> </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> ESTIMATORS_TAB08() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("tab08-estimators");
        propimpl.setDisplayName("Estimators");
        propimpl.setShortDescription("Estimators for model TAB08");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // define the enum
        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Estimator_TAB08.class);


        // key & value
        propimpl.setKey("genomemap.builder.TAB08Estimator.implCode");
        propimpl.setValue("tab08:interval-mle");

        return propimpl;
    }

    /**
     * Supplies the following property: <ul><li>{@code genomemap.builder.KSA00Estimator.implCode =
     * ksa00estimator:conj-gradient}</li></ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> ESTIMATORS_KSA00() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("ksa00-estimators");
        propimpl.setDisplayName("Estimators");
        propimpl.setShortDescription("Estimators for model KSA00");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // define the enum
        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Estimator_KSA00.class);


        // key & value
        propimpl.setKey("genomemap.builder.KSA00Estimator.implCode");
        propimpl.setValue("ksa00estimator:conj-gradient");

        return propimpl;
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.TAB08ModelGenerator.implCode = tab08:1}</li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> GENERATORS_MODEL_TAB08() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("tab08-model-generators");
        propimpl.setDisplayName("TAB08 Model Generators");
        propimpl.setShortDescription("Generates TAB08 model space.");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Generator_Model_TAB08.class);


        // key & value
        propimpl.setKey("genomemap.builder.TAB08ModelGenerator.implCode");
        propimpl.setValue("tab08:1");

        return propimpl;
    }

    /**
     * Properties:
     * <ul>
     *     <li>{@code genomemap.builder.KSA00ModelGenerator.implCode = ksa00:1}</li>
     * </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> GENERATORS_MODEL_KSA00() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("ksa00-model-generators");
        propimpl.setDisplayName("KSA00 Model Generators");
        propimpl.setShortDescription("Generates KSA00 model space.");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.Generator_Model_KSA00.class);


        // key & value
        propimpl.setKey("genomemap.builder.KSA00ModelGenerator.implCode");
        propimpl.setValue("ksa00:1");

        return propimpl;
    }

    /**
     * Supplies the following property: <ul> <li>{@code genomemap.ContigMapType.format = FULL |
     * MINIMAL}</li> </ul>
     *
     * @return a new instance of the property
     */
    public static Property<String> ContigMapType() {

        final Property<String> propimpl = Propertys.ofString();


        // descriptions & display category
        propimpl.setName("contig-map-type");
        propimpl.setDisplayName("Contig Map Type");
        propimpl.setShortDescription("Contig Map Type");
        propimpl.setPropertySet(PropertySets.ALGORITHMS);


        // validator
        propimpl.setPropEditorClass(PropertyEditors_Gen.ConfigMapType.class);


        // key & value
        propimpl.setKey("genomemap.ContigMapType.format");
        propimpl.setValue("MINIMAL");

        return propimpl;
    }

    public static Property<List<String>> TAB08_GeneList() {

        final TwoWayConverter<String, List<String>> cnv = TwoWayConverterS.of_String_List(",",
                                                              TwoWayConverterS.ofString());
        final Property<List<String>> prop = Propertys.ofStringList("tab08-geneList-userOrder",
                                                "User Gene Order", "User specified gene order",
                                                PropertySets.DATA,
                                                "commons.builder.StringList.userOrder", null, cnv);

        prop.setPropEditorClass(PropertyEditors_Gen.TAB08_GeneOrder_PE.class);
        prop.setPersisting(false);

        return prop;
    }
}
